module.exports = {
  deepClone1(origin, target) {
    var target = target || {},
      toStr = Object.prototype.toString,
      arrType = "[object Arrar]";
    for (var key in origin) {
      if (origin.hasOwnProperty(key)) {
        if (typeof origin[key] === "object" && origin[key] !== null) {
          if (origin[key] instanceof RegExp) {
            target[key] = new RegExp(origin[key]);
          } else if (origin[key] instanceof Date) {
            target[key] = new Date(origin[key]);
          } else if (toStr.call(origin[key]) === arrType) {
            target[key] = [];
          } else {
            target[key] = {};
          }
          deepClone1(origin[key], target[key]);
        } else {
          target[key] = origin[key];
        }
      }
    }
    return target;
  },

  deepClone2(obj) {
    if (obj === null) return null;
    if (typeof obj !== "object") return obj;
    if (obj instanceof RegExp) {
      return new RegExp(obj);
    }
    if (obj instanceof Date) {
      return new Date(obj);
    }
    let newObj = new obj.constructor();
    for (let i in obj) {
      if (obj.hasOwnProperty(i)) {
        newObj[i] = deepClone2(obj[i]);
      }
    }
    return newObj;
  },

  deepClone3(data) {
    const type = this.judgeType(data);
    let obj = null;
    if (type == "array") {
      obj = [];
      for (let i = 0; i < data.length; i++) {
        obj.push(this.deepClone(data[i]));
      }
    } else if (type == "object") {
      obj = {};
      for (let key in data) {
        if (data.hasOwnProperty(key)) {
          obj[key] = this.deepClone3(data[key]);
        }
      }
    } else {
      return data;
    }
    return obj;
  },

  judgeType(obj) {
    const toString = Object.prototype.toString;
    const map = {
      "[object Boolean]": "boolean",
      "[object Number]": "number",
      "[object String]": "string",
      "[object Function]": "function",
      "[object Array]": "array",
      "[object Date]": "date",
      "[object RegExp]": "regExp",
      "[object Undefined]": "undefined",
      "[object Null]": "null",
      "[object Object]": "object",
    };
    if (obj instanceof Element) {
      return "element";
    }
    return map[toString.call(obj)];
  },
};
